﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Micrhard.FMCG.Server.Interface;
using Micrhard.FMCG.Server.DataAccess;
using Microhard.Core.DBUtility;
using Micrhard.FMCG.Server.DTO;
using Microhard.Core;
using Micrhard.FMCG.Server.Msg;
using Micrhard.FMCG.Server.Models;
using Microhard.Core.Algorithm;

namespace Micrhard.FMCG.Server.Impl
{
    public class SubKAImpl : ISubKA
    {
        public bool IsNameDuplicate(Models.SubKAModel model)
        {
            MicrhardFMCGServerEntities db = new MicrhardFMCGServerEntities();
            var cnt = db.SubKAs.Count(n => n.Name == model.Name);
            return cnt > 0 ? true : false;
        }

        public Microhard.Core.DBUtility.ExecutedResult Add(Models.SubKAModel model)
        {
            ExecutedResult rtn = new ExecutedResult();
            MicrhardFMCGServerEntities db = new MicrhardFMCGServerEntities();
            var op = model.ToEntity();
            try
            {
                //将当前登录人添加为负责业务员
                var emp = db.Employees.SingleOrDefault(e => e.UserName == this.scope.CurrentUserName);
                op.ManagementScopes.Add(new ManagementScope
                {
                    CreateTime = DateTime.Now,
                    ScopeID = Guid.NewGuid(),
                    SubID = op.SubID,
                    EmployeeID = emp.EmployeeID,
                    Range = (int)Range.Monitor
                });
                //将促销员添加到管理范围汇总
                if (model.SalerEmployees != null)
                {
                    model.SalerEmployees.ForEach(s =>
                    {
                        var se = db.Employees.SingleOrDefault(e => e.EmployeeID == s.EmployeeID);
                        op.ManagementScopes.Add(new ManagementScope
                        {
                            CreateTime = DateTime.Now,
                            ScopeID = Guid.NewGuid(),
                            SubID = op.SubID,
                            EmployeeID = s.EmployeeID,
                            Range = (int)Range.Saler
                        });
                    });
                }

                db.SubKAs.AddObject(op);
                db.SaveChanges();
            }
            catch (System.Exception ex)
            {
                rtn.ErrorMsg.Add(DBOperationFailedStatus.AddFailed, SubKAMsg.AddFailed);
                Log.Error("ISubKA.Add", ex);
            }
            return rtn;
        }

        public Microhard.Core.DBUtility.ExecutedResult Update(Models.SubKAModel model)
        {
            ExecutedResult result = new ExecutedResult();
            MicrhardFMCGServerEntities db = new MicrhardFMCGServerEntities();
            var entity = db.SubKAs.SingleOrDefault(l => l.KAID == model.KAID);
            if (entity != null)
            {
                entity.Address = model.Address;
                entity.Cellphone = model.Cellphone;
                entity.Contractor = model.Contractor;
                if (model.SalerEmployees.Count > 0)
                {
                    List<EmployeeModel> todelete, toadd;
                    var exist = entity.ManagementScopes.Where(p => p.Range == (int)Range.Saler).Select(x => x.Employee.ToModel()).ToList();
                    AlgCompare.DataCompareForCreateAndDelete<EmployeeModel>(exist, model.SalerEmployees, new EmployeeCompaer(), out todelete, out toadd);
                    if (todelete != null)
                    {
                        todelete.ForEach(t =>
                        {
                            var d = db.ManagementScopes.SingleOrDefault(m => m.EmployeeID == t.EmployeeID);
                            db.DeleteObject(d);
                        });
                    }
                    if (toadd != null)
                    {
                        toadd.ForEach(a =>
                        {
                            db.ManagementScopes.AddObject(new ManagementScope
                            {
                                CreateTime = DateTime.Now,
                                ScopeID = Guid.NewGuid(),
                                SubID = model.SubID,
                                EmployeeID = a.EmployeeID,
                                Range = (int)Range.Saler
                            });
                        });
                    }
                }
            }
            try
            {
                db.SaveChanges();
            }
            catch (Exception ex)
            {
                result.ErrorMsg.Add(DBOperationFailedStatus.UpdateFailed, SubKAMsg.UpdateFailed);
                Log.Error("ISubKA.Update", ex);
            }
            return result;
        }

        public Microhard.Core.DBUtility.ExecutedResult Delete(List<Guid> ids)
        {
            ExecutedResult result = new ExecutedResult();
            MicrhardFMCGServerEntities db = new MicrhardFMCGServerEntities();
            var entity = db.SubKAs.Where(l => ids.Contains(l.SubID));
            foreach (var e in entity)
            {
                //是否在使用
                if (e.CheckListSheets.Count == 0 && e.SaleVolumnOfMonths.Count == 0 && e.RealSaleVolumnOfDays.Count == 0
                    && e.SaleStatements.Count == 0 && e.EmployeeCheckIns.Count == 0)
                {
                    var scopes = e.ManagementScopes.ToList();
                    foreach (var s in scopes)
                    {
                        db.ManagementScopes.DeleteObject(s);
                    }
                    db.SubKAs.DeleteObject(e);
                }
                else
                {
                    result.ErrorMsg.Add(DBOperationFailedStatus.DeleteFailed + e.Name, string.Format(SubKAMsg.IsInUsing, e.Name));
                }
            }
            if (result.ErrorMsg.Count == 0)
            {
                try
                {
                    db.SaveChanges();
                }
                catch (Exception ex)
                {
                    result.ErrorMsg.Add(DBOperationFailedStatus.DeleteFailed, SubKAMsg.DeleteFailed);
                    Log.Error("ISubKA.Delete", ex);
                }
            }
            return result;
        }

        public Microhard.Core.DBUtility.ExecutedResult Delete(Models.SubKAModel model)
        {
            throw new NotImplementedException();
        }

        public Models.SubKAModel GetModelByID(Guid id)
        {
            MicrhardFMCGServerEntities db = new MicrhardFMCGServerEntities();
            return db.SubKAs.SingleOrDefault(c => c.SubID == id).ToModel();
        }

        public Models.SubKAModel GetModelByModel(Models.SubKAModel model)
        {
            throw new NotImplementedException();
        }

        public List<Models.SubKAModel> Query(Models.SubKAModel Model, int pageIndex, int pageSize, out int totalCount)
        {
            MicrhardFMCGServerEntities db = new MicrhardFMCGServerEntities();
            var cmp = db.Employees.SingleOrDefault(e => e.UserName == this.scope.CurrentUserName);
            IEnumerable<SubKA> entities = null;
            if (cmp.Range == (int)Range.Manager)
            {
                entities = from b in db.SubKAs
                           where b.KAID == Model.KAID
                           && b.KA.CompanyID == cmp.CompanyID
                           select b;
            }
            else
            {
                entities = from b in db.SubKAs
                           from s in b.ManagementScopes
                           where b.KAID == Model.KAID
                           && b.KA.CompanyID == cmp.CompanyID
                           && s.Range == (int)Range.Monitor
                           && s.EmployeeID == cmp.EmployeeID
                           select b;
            }
            totalCount = entities.Count();
            var pagedEntities = entities.OrderBy(p => p.CustomerCode).Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
            if (pagedEntities != null && pagedEntities.Count > 0)
            {
                var result = pagedEntities.Select(m => m.ToModel()).ToList();
                result.ForEach(i =>
                {
                    i.CanDeleteOrUpdate = cmp.Range == (int)Range.Manager ? true : false;
                });
                return result;
            }
            return new List<SubKAModel>();
        }

        public List<Models.SubKAModel> Query(Models.SubKAModel Model)
        {
            List<SubKAModel> result = new List<SubKAModel>();
            if (Model.ReportQueryForBeginDate == DateTime.MinValue
                || Model.ReportQueryForEndDate == DateTime.MinValue)
                return result;
            DateTime from = Model.ReportQueryForBeginDate;
            DateTime end = Model.ReportQueryForEndDate;
            if (Model.KAID == Guid.Empty)
                return result;
            MicrhardFMCGServerEntities db = new MicrhardFMCGServerEntities();
            var emp = db.Employees.SingleOrDefault(e => e.UserName == this.scope.CurrentUserName);
            List<SubKA> subkas = null;
            if (emp.Range == (int)Range.Monitor)
            {
                subkas = (from s in db.SubKAs
                          from c in s.ManagementScopes
                          where s.KA.CompanyID == emp.CompanyID
                          && c.EmployeeID == emp.EmployeeID
                          && s.KAID == Model.KAID
                          select s).OrderBy(p => p.CustomerCode).ToList();
            }
            else if (emp.Range == (int)Range.Manager)
            {
                subkas = (from s in db.SubKAs
                          where s.KA.CompanyID == emp.CompanyID
                          && s.KAID == Model.KAID
                          select s).OrderBy(p => p.CustomerCode).ToList();
            }
            if (subkas != null && subkas.Count > 0)
            {
                //计算销量信息
                DateTime tbbegin = from;
                tbbegin = tbbegin.AddYears(-1);
                DateTime tbend = end;
                tbend = tbend.AddYears(-1);

                DateTime hbbegin = from;
                hbbegin = hbbegin.AddDays(-1);
                DateTime hbend = end;
                hbend = hbend.AddDays(-1);

                subkas.ForEach(m =>
                {
                    var model = m.ToModel();
                    var list = this.GetSubKASaledVolumn(m.SubID, from, end);
                    model.AmountSaleVolumn = list.Sum(x => x.SaleVolumn).Value;
                    model.SaleCount = list.Sum(x => x.SaleTotalCount).Value;

                    var tblist = this.GetSubKASaledVolumn(m.SubID, tbbegin, tbend);
                    model.TBAmountSaleVolumn = tblist.Sum(x => x.SaleVolumn).Value;

                    var hblist = this.GetSubKASaledVolumn(m.SubID, hbbegin, hbend);
                    model.HBAmountSaleVolumn = tblist.Sum(x => x.SaleVolumn).Value;

                    model.ReportQueryForBeginDate = from;
                    model.ReportQueryForEndDate = end;
                    model.KACode = subkas.First().KA.CustomerCode;

                    result.Add(model);
                });
                result = result.OrderByDescending(p => p.AmountSaleVolumn).ToList();
                //合计
                result.Add(new SubKAModel
                {
                    CustomerCode = string.Empty,
                    Name = "合计",
                    AmountSaleVolumn = result.Sum(p => p.AmountSaleVolumn),
                    TBAmountSaleVolumn = result.Sum(p => p.TBAmountSaleVolumn),
                    HBAmountSaleVolumn = result.Sum(p => p.HBAmountSaleVolumn),
                    SaleCount = result.Sum(p => p.SaleCount),
                    StoreAmount = result.Sum(p => p.StoreAmount),
                    StoreCount = result.Sum(p => p.StoreCount),
                    SubID = Guid.Empty,
                    ReportQueryForBeginDate = from,
                    ReportQueryForEndDate = end,
                    KACode = subkas.First().KA.CustomerCode
                });
            }
            return result;
        }

        private List<ProductSaledOfDay> GetSubKASaledVolumn(Guid subkaID, DateTime from, DateTime end)
        {
            MicrhardFMCGServerEntities db = new MicrhardFMCGServerEntities();
            return db.ProductSaledOfDays.Where(s => s.SubKAID == subkaID && s.DayOfSaled >= from && s.DayOfSaled <= end).ToList();
        }

        public Microhard.Core.DBUtility.ScopeResult scope
        {
            set;
            get;
        }


        public List<SubKAModel> GetKAByWeixinOpenID(string weixinOpenID)
        {
            MicrhardFMCGServerEntities db = new MicrhardFMCGServerEntities();
            return (from k in db.SubKAs
                    from s in k.ManagementScopes
                    where s.Employee.WeixinOpenID == weixinOpenID
                    select k).ToList().Select(t => t.ToModel()).ToList();
        }


        public bool IsKACode(string code)
        {
            MicrhardFMCGServerEntities db = new MicrhardFMCGServerEntities();
            var cnt = db.SubKAs.Count(s => s.CustomerCode == code);
            return cnt > 0 ? true : false;
        }


        public bool IsUserManageKA(string weixinOpenID, string kaCode)
        {
            MicrhardFMCGServerEntities db = new MicrhardFMCGServerEntities();
            var cnt = db.ManagementScopes.Count(k => k.SubKA.CustomerCode == kaCode && k.Employee.WeixinOpenID == weixinOpenID);
            return cnt > 0 ? true : false;
        }


        public List<SubKAModel> GetSubKAByKAID(Guid kaid)
        {
            MicrhardFMCGServerEntities db = new MicrhardFMCGServerEntities();
            var cmp = db.Employees.SingleOrDefault(e => e.UserName == this.scope.CurrentUserName);
            return (from b in db.SubKAs
                    where this.scope.PKID.Contains(b.SubID)
                    && b.KAID == kaid
                    && b.KA.CompanyID == cmp.CompanyID
                    select b).ToList().Select(t => t.ToModel()).ToList();
        }

        public bool IsCustomeCodeDuplicate(string code)
        {
            MicrhardFMCGServerEntities db = new MicrhardFMCGServerEntities();
            var cnt = db.SubKAs.Count(n => n.CustomerCode == code);
            return cnt > 0 ? true : false;
        }


        public ExecutedResult UpdateSubKALocation(SubKAModel model)
        {
            ExecutedResult result = new ExecutedResult();
            MicrhardFMCGServerEntities db = new MicrhardFMCGServerEntities();
            var entity = db.SubKAs.SingleOrDefault(l => l.SubID == model.SubID);
            if (entity != null)
            {
                entity.Baidulng = model.Baidulng;
                entity.Baidulat = model.Baidulat;
            }
            try
            {
                db.SaveChanges();
            }
            catch (Exception ex)
            {
                result.ErrorMsg.Add(DBOperationFailedStatus.UpdateFailed, SubKAMsg.UpdateFailed);
                Log.Error("ISubKA.UpdateSubKALocation", ex);
            }
            return result;
        }


        public List<SubKAModel> GetKAByUserName(string userName)
        {
            MicrhardFMCGServerEntities db = new MicrhardFMCGServerEntities();
            return (from k in db.SubKAs
                    from s in k.ManagementScopes
                    where s.Employee.UserName == userName
                    select k).ToList().Select(t => t.ToModel()).ToList();
        }


        public SubKAProtalInfoModel GetProtalInfo(Guid subkaID, DateTime protalDate)
        {
            MicrhardFMCGServerEntities db = new MicrhardFMCGServerEntities();
            var subka = db.SubKAs.SingleOrDefault(i => i.SubID == subkaID);
            var start = protalDate.Date;
            var end = start.AddDays(1);
            var ckin = subka.EmployeeCheckIns.Where(e => e.CreateTime >= start && e.CreateTime <= end).ToList();
            var imgs = db.ProductDisplayImages.Where(i => i.CreateTime >= start && i.CreateTime <= end && i.SubKACode == subka.CustomerCode).ToList();
            SubKAProtalInfoModel result = new SubKAProtalInfoModel();
            if (ckin.Count > 0)
            {
                result.CheckIn = ckin.Select(t => t.ToModel()).ToList();
            }
            if (imgs.Count > 0)
            {
                result.SubKAImage = imgs.Select(t => t.ToModel()).ToList();
            }
            return result;
        }


        public List<ProductSaledOfDayModel> GetSubKASaledProductDetail(Guid subkaID, DateTime fromdate, DateTime end, string sys)
        {
            List<ProductSaledOfDayModel> result = new List<ProductSaledOfDayModel>();
            MicrhardFMCGServerEntities db = new MicrhardFMCGServerEntities();
            if (subkaID == Guid.Empty)
            {
                var emp = db.Employees.SingleOrDefault(c => c.UserName == this.scope.CurrentUserName);
                var cmp = emp.CompanyID;
                var allprd = db.ProductSaleMappings.Where(p => p.KA.CompanyID == cmp && p.KA.CustomerCode == sys).ToList();
                allprd.ForEach(i =>
                {
                    var saled = from s in i.ProductSaledOfDays
                                where s.DayOfSaled >= fromdate && s.DayOfSaled <= end
                                && s.HQCompanyCode == sys && s.CompanyID == cmp
                                select s;
                    result.Add(new ProductSaledOfDayModel
                    {
                        CompanyID = cmp.Value,
                        HQCompanyCode = sys,
                        ProductCode = i.CustomerCode,
                        ProductName = i.Product.Mark,
                        SaleTotalCount = saled.Sum(x => x.SaleTotalCount.Value),
                        SaleVolumn = saled.Sum(x => x.SaleVolumn.Value),
                        SalingPrdID = i.PrdDepID
                    });
                });
            }
            else
            {
                var subka = db.SubKAs.SingleOrDefault(s => s.SubID == subkaID);
                if (subka != null)
                {
                    var allprds = (from k in subka.ProductSaledOfDays
                                   where k.DayOfSaled >= fromdate && k.DayOfSaled <= end
                                   select k).ToList();
                    allprds.ForEach(i =>
                    {
                        var exist = result.SingleOrDefault(w => w.ProductCode == i.ProductCode);
                        if (exist != null)
                        {
                            exist.SaleVolumn += i.SaleVolumn.Value;
                            exist.SaleTotalCount += i.SaleTotalCount.Value;
                        }
                        else
                        {
                            result.Add(i.ToModel());
                        }
                    });
                }
            }


            result = result.OrderByDescending(r => r.SaleVolumn).ToList();
            result.Add(new ProductSaledOfDayModel
            {
                ProductName = "合计",
                SaleVolumn = result.Sum(p => p.SaleVolumn)
            });
            return result;
        }


        public ExecutedResult AssignMonitor(SubKAModel model)
        {
            ExecutedResult result = new ExecutedResult();
            MicrhardFMCGServerEntities db = new MicrhardFMCGServerEntities();
            var entity = db.SubKAs.SingleOrDefault(l => l.SubID == model.SubID);
            if (entity != null)
            {
                var ms = entity.ManagementScopes.SingleOrDefault(w => w.Range == (int)Range.Monitor);
                ms.EmployeeID = model.KAMonitorID;
            }
            try
            {
                db.SaveChanges();
            }
            catch (Exception ex)
            {
                result.ErrorMsg.Add(DBOperationFailedStatus.UpdateFailed, SubKAMsg.UpdateFailed);
                Log.Error("ISubKA.AssignMonitor", ex);
            }
            return result;
        }
    }
}
